﻿#include "TcpClient.h"
#include "ui_TcpClient.h"

TcpClient::TcpClient(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::TcpClient)
{
    ui->setupUi(this);

    initUi();
}

TcpClient::~TcpClient()
{
    delete ui;
}

void TcpClient::initUi()
{
    // 菜单栏
    QToolBar *tbTop  = new QToolBar("TopBar", this);
    // tbTop->setIconSize(QSize(16, 16));

    // 初始放在顶部
    addToolBar(Qt::TopToolBarArea, tbTop);

    // 允许用户拖动
    tbTop->setMovable(true);
    // 允许拖出来变成独立浮动窗口
    tbTop->setFloatable(true);

    // 上下左右四个方向都能停靠
    tbTop->setAllowedAreas(Qt::AllToolBarAreas);

    /* 4. 随便放点 action，让工具栏有点东西 ------------------------------- */
    connectServerAct  = new QAction(QStringLiteral("连接服务器"),  this);
    disconnectServerAct   = new QAction(QStringLiteral("断开连接"),  this);
    clearAct        = new QAction(QStringLiteral("清空文本框"), this);
    quitAct         = new QAction(QStringLiteral("退出"), this);
    tbTop->addAction(connectServerAct);
    tbTop->addAction(disconnectServerAct);
    tbTop->addAction(clearAct);
    tbTop->addAction(quitAct);

    // connect
    connect(connectServerAct, &QAction::triggered, this, &TcpClient::onConnectServerAct);
    connect(disconnectServerAct, &QAction::triggered, this, &TcpClient::onDisconnectServerAct);
    connect(clearAct, &QAction::triggered, this, &TcpClient::onClearAct);
    connect(quitAct, &QAction::triggered, this, &TcpClient::onQuitAct);

    labSocketState = new QLabel(QStringLiteral("Socket状态:"));
    labSocketState->setMinimumWidth(250);
    ui->statusbar->addWidget(labSocketState);

    // 本机Ip
    QString localIp = getLocalIp();

    this->setWindowTitle(this->windowTitle() + QStringLiteral("-----本机IP:") + localIp);

    ui->serverAddr->addItem(localIp);

    // 客户端Tcp
    clientTcp = new QTcpSocket(this);

    connect(clientTcp, &QTcpSocket::connected, this, &TcpClient::onConnected);
    connect(clientTcp, &QTcpSocket::disconnected, this, &TcpClient::onDisConnected);
    connect(clientTcp, &QTcpSocket::stateChanged, this, &TcpClient::onSocketStateChanged);
    connect(clientTcp, &QTcpSocket::readyRead, this, &TcpClient::onSocketReadyRead);
}

QString TcpClient::getLocalIp()
{
    // 获取本机IPv4地址
    QString hostName = QHostInfo::localHostName();
    QHostInfo hostInfo = QHostInfo::fromName(hostName);
    QString localIp = "";
    QList<QHostAddress> addrList = hostInfo.addresses();
    if(!addrList.isEmpty())
        for (int i = 0; i < addrList.count(); i++) {
            QHostAddress aHost = addrList.at(i);
            if(QAbstractSocket::IPv4Protocol == aHost.protocol())
            {
                localIp = aHost.toString();
                break;
            }
        }
    return localIp;
}


void TcpClient::on_btnSend_clicked()
{
    // 发送数据
    QString msg = ui->edtSend->text();
    ui->plainTextEdit->appendPlainText("[out] " + msg);
    ui->edtSend->clear();
    ui->edtSend->setFocus();

    QByteArray str = msg.toUtf8();
    str.append('\n');
    clientTcp->write(str);
}

void TcpClient::onConnectServerAct()
{
    // 连接到服务器按钮
    QString addr = ui->serverAddr->currentText();
    quint16 port = ui->port->value();
    clientTcp->connectToHost(addr, port);
}

void TcpClient::onDisconnectServerAct()
{
    if(clientTcp->state() == QAbstractSocket::ConnectedState)
    {
        clientTcp->disconnectFromHost();
    }
}

void TcpClient::onClearAct()
{
    ui->plainTextEdit->clear();
}

void TcpClient::onQuitAct()
{
    this->close();
}

void TcpClient::onConnected()
{
    ui->plainTextEdit->appendPlainText(QStringLiteral("**已连接到服务器"));
    ui->plainTextEdit->appendPlainText(QStringLiteral("**peer address: ") + clientTcp->peerAddress().toString());
    ui->plainTextEdit->appendPlainText(QStringLiteral("**peer port: ") + QString::number(clientTcp->peerPort()));
    connectServerAct->setEnabled(false);
    disconnectServerAct->setEnabled(true);
}

void TcpClient::onDisConnected()
{
    ui->plainTextEdit->appendPlainText(QStringLiteral("**已断开与服务器的连接"));
    connectServerAct->setEnabled(true);
    disconnectServerAct->setEnabled(false);
}

void TcpClient::onSocketStateChanged(QAbstractSocket::SocketState socketState)
{
    // socket状态变化
    switch(socketState)
    {
    case QAbstractSocket::UnconnectedState  :
        labSocketState->setText(QStringLiteral("socket状态:UnconnectedState"));
        break;
    case QAbstractSocket::HostLookupState   :
        labSocketState->setText(QStringLiteral("socket状态:HostLookupState"));
        break;
    case QAbstractSocket::ConnectingState   :
        labSocketState->setText(QStringLiteral("socket状态:ConnectingState"));
        break;
    case QAbstractSocket::ConnectedState    :
        labSocketState->setText(QStringLiteral("socket状态:ConnectedState"));
        break;
    case QAbstractSocket::BoundState        :
        labSocketState->setText(QStringLiteral("socket状态:BoundState"));
        break;
    case QAbstractSocket::ListeningState    :
        labSocketState->setText(QStringLiteral("socket状态:ListeningState"));
        break;
    case QAbstractSocket::ClosingState      :
        labSocketState->setText(QStringLiteral("socket状态:ClosingState"));
        break;
    }
}

void TcpClient::onSocketReadyRead()
{
    while(clientTcp->canReadLine())
    {
        ui->plainTextEdit->appendPlainText("[in]" + clientTcp->readLine());
    }
}
